"""windows端接收并显示视频，主动接收网址，后运行发送控制的字节数"""
# coding=utf-8
import socket
import cv2
import threading
import struct
import numpy


class Camera_Connect_Object:

    def __init__(self, vid_add=("127.0.0.1", 8848)):  # 客户端获取视频的
        self.add_port = vid_add
        self.name = self.add_port[0] + " Camera"
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.resolution = [640, 480]
        self.src = 888 + 30  # 双方确定传输帧数，（888）为校验值
        self.interval = 0  # 图片播放时间间隔
        self.img_fps = 30  # 每秒传输多少帧数


    def Set_socket(self):
        self.client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    def Socket_Connect(self):
        """创建与服务器视频转发端口的连接"""
        self.Set_socket()
        try:
            self.client.connect(self.add_port)

            print("RemoteVideo IP is %s:%d" % (self.add_port[0], self.add_port[1]))
        except:
            print('vid link failed')

    def RT_Image(self):
        # 按照格式打包发送帧数和分辨率
        self.client.send(struct.pack("lhh", self.src, self.resolution[0], self.resolution[1]))
        while True:
            info = struct.unpack("lhh", self.client.recv(8))
            buf_size = info[0]  # 获取读的图片总长度
            if buf_size:
                try:
                    self.buf = b""  # 代表bytes类型
                    temp_buf = self.buf
                    while buf_size:  # 读取每一张图片的长度
                        temp_buf = self.client.recv(buf_size)
                        buf_size -= len(temp_buf)
                        self.buf += temp_buf  # 获取图片
                        data = numpy.frombuffer(self.buf, dtype='int8')  # 按uint8转换为图像矩阵
                        self.image = cv2.imdecode(data, 1)  # 图像解码
                        # return self.image
                        cv2.imshow(self.name, self.image)  # 展示图片
                except:
                    pass
                finally:
                    if cv2.waitKey(10) == 27:  # 每10ms刷新一次图片，按‘ESC’（27）退出
                        self.client.close()
                        cv2.destroyAllWindows()
                        break

    def Get_Image(self):
        # 按照格式打包发送帧数和分辨率
        #self.name = self.add_port[0] + " Camera"
        self.client.send(struct.pack("lhh", self.src, self.resolution[0], self.resolution[1]))
        info = struct.unpack("lhh", self.client.recv(8))
        buf_size = info[0]  # 获取读的图片总长度
        if buf_size:
            try:
                self.buf = b""  # 代表bytes类型
                temp_buf = self.buf
                while buf_size:  # 读取每一张图片的长度
                    temp_buf = self.client.recv(buf_size)
                    buf_size -= len(temp_buf)
                    self.buf += temp_buf  # 获取图片
                    data = numpy.frombuffer(self.buf, dtype='int8')  # 按int8转换为图像矩阵
                    self.image = cv2.imdecode(data, 1)  # 图像解码
                return self.image
            except:
                pass

    def Get_Data(self):
        showThread = threading.Thread(target=self.RT_Image())
        showThread.setDaemon(True)
        showThread.start()


if __name__ == '__main__':
    camera = Camera_Connect_Object()  # 建立对象
    camera.add_port = tuple(camera.add_port)  # 列表转换为元组
    camera.Socket_Connect()
    a = threading.Thread(target=camera.Get_Data, args=())
    a.start()
